package common.controls.item
{
	
	
	import common.controls.item.events.ItemEvent;
	import common.controls.utils.FilterUtils;
	
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.ui.Mouse;
	import flash.utils.Dictionary;
	
	import kernel.application.ApplicationDisplay;
	
	/**  
	 * 
	 * @author carrey
	 * */ 
	public class ItemDragManager
	{
		private static var _ins:ItemDragManager;
		
		private var _stage:Stage;
		private var _dict:Dictionary;
		private var _ptOrigin:Point;
		private var _ptOffset:Point;
		
		private var _hadSendBeginEvent:Boolean = true;
		private var _currentDragOutContainer:ItemContainer = null;
		private var _dragImageContainer:Sprite;
		private var _currentDraggingImage:Bitmap = null;
		
		public function ItemDragManager()
		{
			init();
		}
		
		private function init():void
		{
			_stage = ApplicationDisplay.stage;
			_dict = new Dictionary();
			_ptOrigin = new Point();
			_ptOffset = new Point();
			
			_dragImageContainer = new Sprite();
			_currentDraggingImage = new Bitmap();
			_dragImageContainer.addChild( _currentDraggingImage );
			_dragImageContainer.mouseChildren = false;
			_dragImageContainer.mouseEnabled = false;
		}
		
		public static function get instance():ItemDragManager
		{
			if( _ins==null )
			{
				_ins = new ItemDragManager();
			}
			return _ins;
		}
		
		public function addContainer( container:ItemContainer ):void
		{
			if( _dict[container] != null ) return;
			
			_dict[container] = container;
			
			container.addEventListener( MouseEvent.DOUBLE_CLICK, onDoubleClick, false, 0, true );
			container.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true );
			container.addEventListener( MouseEvent.MOUSE_OVER, onMouseOver, false, 0, true );
			container.addEventListener( MouseEvent.MOUSE_OUT, onMouseOut, false, 0, true );
		}
		
		public function removeContainer( container:ItemContainer ):void
		{
			if( _dict[container] != null )
			{
				delete _dict[container];
				
				container.removeEventListener( MouseEvent.DOUBLE_CLICK, onDoubleClick );
				container.removeEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
				container.removeEventListener( MouseEvent.MOUSE_OVER, onMouseOver );
				container.removeEventListener( MouseEvent.MOUSE_OUT, onMouseOut );
			}
		}
		
		private function onDoubleClick( e:MouseEvent ):void
		{
			var container:ItemContainer = e.currentTarget as ItemContainer;
			
			if( !container.isLock )
				container.dispatchEvent( new ItemEvent( ItemEvent.DOUBLE_CLICK, container ) );
		}
		
		private function onMouseDown( e:MouseEvent ):void
		{
			if( _currentDragOutContainer==null )
			{
				_currentDragOutContainer = e.currentTarget as ItemContainer;
				if( _currentDragOutContainer.item==null || _currentDragOutContainer.isLock || (_currentDragOutContainer.dragMode & ItemDragMode.CAN_DRAG_OUT)==0 )
				{
					_currentDragOutContainer = null;
					return;
				}
				
				_stage.addEventListener( MouseEvent.MOUSE_MOVE, onStageMouseMove, false, 0, true );
				_stage.addEventListener( MouseEvent.MOUSE_UP, onStageMouseUp, false, 0, true );
				
				_hadSendBeginEvent = false;
				
				_ptOffset = _currentDragOutContainer.localToGlobal( _ptOrigin );
				_ptOffset.x = int(_ptOffset.x - e.stageX);
				_ptOffset.y = int(_ptOffset.y - e.stageY);
				
				_currentDraggingImage.x = int(_ptOffset.x);
				_currentDraggingImage.y = int(_ptOffset.y);
			}
		}
		
		private function onStageMouseMove( e:MouseEvent ):void
		{
			if( _currentDragOutContainer==null ) return;
			if( !_hadSendBeginEvent )
			{
				_hadSendBeginEvent = true;
				_currentDragOutContainer.dispatchEvent( new ItemEvent( ItemEvent.DRAG_ITEM_START, _currentDragOutContainer ) );
				
				_currentDraggingImage.bitmapData = _currentDragOutContainer.getShortcutImage();
				
				_dragImageContainer.x = int(e.stageX);
				_dragImageContainer.y = int(e.stageY);
				_stage.addChild( _dragImageContainer );
				_dragImageContainer.startDrag();
			}
			
			var container:ItemContainer = e.target as ItemContainer;
			if( container != null && container != _currentDragOutContainer && !container.isLock && (container.dragMode & ItemDragMode.CAN_DRAG_IN)>0 )
			{
				var event:ItemEvent = new ItemEvent( ItemEvent.DRAG_ITEM_OVER_AND_MOVING, _currentDragOutContainer )
				container.dispatchEvent( event );
				if( event.isAcceptCurrentItem )
				{
					_currentDraggingImage.filters = null;
				}
				else
				{
					_currentDraggingImage.filters = FilterUtils.getRedGlowFilter();
				}
			}
		}
		
		private function onStageMouseUp( e:MouseEvent ):void
		{
			_stage.removeEventListener( MouseEvent.MOUSE_MOVE, onStageMouseMove );
			_stage.removeEventListener( MouseEvent.MOUSE_UP, onStageMouseUp );
			
			var container:ItemContainer = e.target as ItemContainer;
			if( container != null && container != _currentDragOutContainer && !container.isLock && (container.dragMode & ItemDragMode.CAN_DRAG_IN)>0 )
			{
				var event:ItemEvent = new ItemEvent( ItemEvent.DRAG_ITEM_DROPPED, _currentDragOutContainer )
				container.dispatchEvent( event );
				if( event.isAcceptCurrentItem )
				{
					_currentDragOutContainer.dispatchEvent( new ItemEvent( ItemEvent.DRAG_ITEM_TO_OTHER_CONTAINER, _currentDragOutContainer ) );
				}
				else
				{
					_currentDragOutContainer.dispatchEvent( new ItemEvent( ItemEvent.DRAG_ITEM_DISCARDED, _currentDragOutContainer ) );
				}
			}
			else if( container != _currentDragOutContainer )
			{
				_currentDragOutContainer.dispatchEvent( new ItemEvent( ItemEvent.DRAG_ITEM_DISCARDED, _currentDragOutContainer ) );
			}
			
			if( _dragImageContainer.parent != null )
			{
				_stage.removeChild( _dragImageContainer );
				_dragImageContainer.stopDrag();
			}
			
			_currentDragOutContainer = null;
			if( _currentDraggingImage.bitmapData != null )
			{
				_currentDraggingImage.bitmapData.dispose();
				_currentDraggingImage.bitmapData = null;
			}
		}
		
		private function onMouseOver( e:MouseEvent ):void
		{
			if( _currentDragOutContainer==null ) return;
			
			var container:ItemContainer = e.currentTarget as ItemContainer;
			if( container != _currentDragOutContainer && !container.isLock && (container.dragMode & ItemDragMode.CAN_DRAG_IN)>0 )
			{
				var event:ItemEvent = new ItemEvent( ItemEvent.DRAG_ITEM_OVER, _currentDragOutContainer )
				container.dispatchEvent( event );
				if( event.isAcceptCurrentItem )
				{
					_currentDraggingImage.filters = null;
				}
				else
				{
					_currentDraggingImage.filters = FilterUtils.getRedGlowFilter();
				}
			}
		}
		
		private function onMouseOut( e:MouseEvent ):void
		{
			if( _currentDragOutContainer==null ) return;
			var container:ItemContainer = e.currentTarget as ItemContainer;
			if( container != _currentDragOutContainer && !container.isLock && (container.dragMode & ItemDragMode.CAN_DRAG_IN)>0 )
			{
				container.dispatchEvent( new ItemEvent( ItemEvent.DRAG_ITEM_OUT, _currentDragOutContainer ) );
				_currentDraggingImage.filters = null;
			}
		}
	}
}